package com.dyava.commons.defaultvalue;

import com.dyava.commons.defaultvalue.annotation.*;
import javassist.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

public class DefaultValueBuilderFactory {
	private ConcurrentHashMap<Class<?>, DefaultValueBuilder> defaultValueBuilderMap = new ConcurrentHashMap<Class<?>, DefaultValueBuilder>();

	public DefaultValueBuilder getDefaultValueBuilder(Class<?> clazz) throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException, IntrospectionException{
		DefaultValueBuilder defaultValueBuilder =  defaultValueBuilderMap.get(clazz);
		if(defaultValueBuilder==null){
			synchronized (clazz) {
				defaultValueBuilder = defaultValueBuilderMap.get(clazz);
				if(defaultValueBuilder==null){
			        defaultValueBuilder = createClass(clazz);
			        defaultValueBuilderMap.put(clazz, defaultValueBuilder);
				}
			}
		}
		return defaultValueBuilder;
	}


	private DefaultValueBuilder createClass(Class<?> clazz) throws NotFoundException, IntrospectionException,
			CannotCompileException, InstantiationException, IllegalAccessException {
		DefaultValueBuilder defaultValueBuilder;
		ClassPool pool = ClassPool.getDefault();pool.insertClassPath(new ClassClassPath(DefaultValueBuilder.class));
		CtClass DefaultValueBuilderInterfaceCt = pool.getCtClass(DefaultValueBuilder.class.getName());
		CtClass defaultValueBuilderCt = pool.makeClass(DefaultValueBuilder.class.getName()+clazz.getSimpleName()+System.currentTimeMillis());
		defaultValueBuilderCt.setInterfaces(new CtClass[]{DefaultValueBuilderInterfaceCt});

		addMethodCreate(clazz, defaultValueBuilderCt);
		addMethodFillForce(clazz, defaultValueBuilderCt);
		addMethodFillSafe(clazz, defaultValueBuilderCt);
		
		Class<?> defaultValueBuilderClass = defaultValueBuilderCt.toClass();
		defaultValueBuilder = (DefaultValueBuilder) defaultValueBuilderClass.newInstance();
		return defaultValueBuilder;
	}


	private void addMethodCreate(Class<?> clazz, CtClass defaultValueBuilderCt) throws IntrospectionException, CannotCompileException {
		AllDefault allDefault = clazz.getAnnotation(AllDefault.class);
		StringBuilder codeTmpSb = new StringBuilder()
		.append("public Object create() {\r\n")
		.append("	#CLASS obj = new #CLASS();\r\n")
		.append("	#SETLINES\r\n")
		.append("	return obj;\r\n")
		.append("}");
		
		String codeTmp = codeTmpSb.toString();
		List<String> setLineList = new ArrayList<String>();
		BeanInfo beanInfo = Introspector.getBeanInfo(clazz);  
		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();  
		for (PropertyDescriptor property : propertyDescriptors) {
		    String key = property.getName();  
		    Field field = FieldUtils.getField(clazz, key, true);
		    if(field!=null){
				{
					IgnoreDefault defaultAnn = field.getAnnotation(IgnoreDefault.class);
					if(defaultAnn!=null){
						continue;
					}
				}
		    	{
			    	StringDefault defaultAnn = field.getAnnotation(StringDefault.class);
			    	if(defaultAnn!=null){
			        	String defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(\"",defaultValue,"\");"));
			    		continue;
			    	}
		    	}
		    	{
			    	BooleanDefault defaultAnn = field.getAnnotation(BooleanDefault.class);
			    	if(defaultAnn!=null){
			        	boolean defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Boolean.valueOf(",defaultValue,"));"));
			    		continue;
			    	}
		    	}
		    	{
			    	ShortDefault defaultAnn = field.getAnnotation(ShortDefault.class);
			    	if(defaultAnn!=null){
			        	short defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Short.valueOf((short)",defaultValue,"));"));
			    		continue;
			    	}
		    	}
		    	{
			    	IntegerDefault defaultAnn = field.getAnnotation(IntegerDefault.class);
			    	if(defaultAnn!=null){
			        	int defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Integer.valueOf(",defaultValue,"));"));
			    		continue;
			    	}
		    	}
		    	{
			    	LongDefault defaultAnn = field.getAnnotation(LongDefault.class);
			    	if(defaultAnn!=null){
			        	long defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Long.valueOf(",defaultValue,"L));"));
			    		continue;
			    	}
		    	}
		    	{
			    	FloatDefault defaultAnn = field.getAnnotation(FloatDefault.class);
			    	if(defaultAnn!=null){
			        	float defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Float.valueOf(",defaultValue,"F));"));
			    		continue;
			    	}
		    	}
		    	{
			    	DoubleDefault defaultAnn = field.getAnnotation(DoubleDefault.class);
			    	if(defaultAnn!=null){
			        	double defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Double.valueOf(",defaultValue,"));"));
			    		continue;
			    	}
		    	}
		    	{
			    	DateDefaultNow defaultAnn = field.getAnnotation(DateDefaultNow.class);
			    	if(defaultAnn!=null){
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(org.apache.commons.lang3.time.DateUtils.truncate(new java.util.Date(),"+defaultAnn.truncate()+"));"));
			    		continue;
			    	}
		    	}
		    	{
			    	SqlDateDefaultNow defaultAnn = field.getAnnotation(SqlDateDefaultNow.class);
			    	if(defaultAnn!=null){
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(new java.sql.Date(java.lang.System.currentTimeMillis()));"));
			    		continue;
			    	}
		    	}
		    	{
			    	SqlTimeDefaultNow defaultAnn = field.getAnnotation(SqlTimeDefaultNow.class);
			    	if(defaultAnn!=null){
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(new java.sql.Time(java.lang.System.currentTimeMillis()));"));
			    		continue;
			    	}
		    	}
		    	{
		    		BigDecimalDefault defaultAnn = field.getAnnotation(BigDecimalDefault.class);
			    	if(defaultAnn!=null){
			        	String defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(new java.math.BigDecimal(\"",defaultValue,"\"));"));
			    		continue;
			    	}
		    	}
				{
					if(allDefault !=null){
						if(field.getType().equals(String.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(\"\");"));
						}else if(field.getType().equals(Boolean.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Boolean.valueOf(false));"));
						}else if(field.getType().equals(Short.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Short.valueOf((short)0));"));
						}else if(field.getType().equals(Integer.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Integer.valueOf(0));"));
						}else if(field.getType().equals(Long.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Long.valueOf(0L));"));
						}else if(field.getType().equals(Float.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Float.valueOf(0.0F));"));
						}else if(field.getType().equals(Double.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Double.valueOf(0.0));"));
						}else if(field.getType().equals(BigDecimal.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(java.math.BigDecimal.ZERO);"));
						}
					}
				}
			}
		}
		String setlines = StringUtils.join(setLineList,"\r\n\t");
		String code  = StringUtils.replace(codeTmp,"#CLASS", clazz.getName());
		code = StringUtils.replace(code,"#SETLINES", setlines);
		CtMethod methodBuildCt = CtNewMethod.make(code,defaultValueBuilderCt);
		defaultValueBuilderCt.addMethod(methodBuildCt);
	};
	private void addMethodFillForce(Class<?> clazz, CtClass defaultValueBuilderCt) throws IntrospectionException, CannotCompileException {
		AllDefault allDefault = clazz.getAnnotation(AllDefault.class);
		StringBuilder codeTmpSb = new StringBuilder()
		.append("public void fillForce(Object o) {\r\n")
		.append("	#CLASS obj = (#CLASS)o;\r\n")
		.append("	#SETLINES\r\n")
		.append("}");
		
		String codeTmp = codeTmpSb.toString();
		List<String> setLineList = new ArrayList<String>();
		BeanInfo beanInfo = Introspector.getBeanInfo(clazz);  
		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();  
		for (PropertyDescriptor property : propertyDescriptors) {
		    String key = property.getName();  
		    Field field = FieldUtils.getField(clazz, key, true);
		    if(field!=null){
				{
					IgnoreDefault defaultAnn = field.getAnnotation(IgnoreDefault.class);
					if(defaultAnn!=null){
						continue;
					}
				}
		    	{
			    	StringDefault defaultAnn = field.getAnnotation(StringDefault.class);
			    	if(defaultAnn!=null){
			        	String defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(\"",defaultValue,"\");"));
			    		continue;
			    	}
		    	}
		    	{
			    	BooleanDefault defaultAnn = field.getAnnotation(BooleanDefault.class);
			    	if(defaultAnn!=null){
			        	boolean defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Boolean.valueOf(",defaultValue,"));"));
			    		continue;
			    	}
		    	}
		    	{
			    	ShortDefault defaultAnn = field.getAnnotation(ShortDefault.class);
			    	if(defaultAnn!=null){
			        	short defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Short.valueOf((short)",defaultValue,"));"));
			    		continue;
			    	}
		    	}
		    	{
			    	IntegerDefault defaultAnn = field.getAnnotation(IntegerDefault.class);
			    	if(defaultAnn!=null){
			        	int defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Integer.valueOf(",defaultValue,"));"));
			    		continue;
			    	}
		    	}
		    	{
			    	LongDefault defaultAnn = field.getAnnotation(LongDefault.class);
			    	if(defaultAnn!=null){
			        	long defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Long.valueOf(",defaultValue,"L));"));
			    		continue;
			    	}
		    	}
		    	{
			    	FloatDefault defaultAnn = field.getAnnotation(FloatDefault.class);
			    	if(defaultAnn!=null){
			        	float defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Float.valueOf(",defaultValue,"F));"));
			    		continue;
			    	}
		    	}
		    	{
			    	DoubleDefault defaultAnn = field.getAnnotation(DoubleDefault.class);
			    	if(defaultAnn!=null){
			        	double defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Double.valueOf(",defaultValue,"));"));
			    		continue;
			    	}
		    	}
		    	{
			    	DateDefaultNow defaultAnn = field.getAnnotation(DateDefaultNow.class);
			    	if(defaultAnn!=null){
			    		Method writeMethod = property.getWriteMethod();
						setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(org.apache.commons.lang3.time.DateUtils.truncate(new java.util.Date(),"+defaultAnn.truncate()+"));"));
			    		continue;
			    	}
		    	}
		    	{
			    	SqlDateDefaultNow defaultAnn = field.getAnnotation(SqlDateDefaultNow.class);
			    	if(defaultAnn!=null){
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(new java.sql.Date(java.lang.System.currentTimeMillis()));"));
			    		continue;
			    	}
		    	}
		    	{
			    	SqlTimeDefaultNow defaultAnn = field.getAnnotation(SqlTimeDefaultNow.class);
			    	if(defaultAnn!=null){
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(new java.sql.Time(java.lang.System.currentTimeMillis()));"));
			    		continue;
			    	}
		    	}
		    	{
		    		BigDecimalDefault defaultAnn = field.getAnnotation(BigDecimalDefault.class);
			    	if(defaultAnn!=null){
			        	String defaultValue = defaultAnn.value();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(new java.math.BigDecimal(\"",defaultValue,"\"));"));
			    		continue;
			    	}
		    	}
				{
					if(allDefault !=null){
						if(field.getType().equals(String.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(\"\");"));
						}else if(field.getType().equals(Boolean.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Boolean.valueOf(false));"));
						}else if(field.getType().equals(Short.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Short.valueOf((short)0));"));
						}else if(field.getType().equals(Integer.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Integer.valueOf(0));"));
						}else if(field.getType().equals(Long.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Long.valueOf(0L));"));
						}else if(field.getType().equals(Float.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Float.valueOf(0.0F));"));
						}else if(field.getType().equals(Double.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Double.valueOf(0.0));"));
						}else if(field.getType().equals(BigDecimal.class)){
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(java.math.BigDecimal.ZERO);"));
						}
					}
				}
			}
		}
		String setlines = StringUtils.join(setLineList,"\r\n\t");
		String code  = StringUtils.replace(codeTmp,"#CLASS", clazz.getName());
		code = StringUtils.replace(code,"#SETLINES", setlines);
		CtMethod methodBuildCt = CtNewMethod.make(code,defaultValueBuilderCt);
		defaultValueBuilderCt.addMethod(methodBuildCt);
	};
	

	private void addMethodFillSafe(Class<?> clazz, CtClass defaultValueBuilderCt) throws IntrospectionException, CannotCompileException {
		AllDefault allDefault = clazz.getAnnotation(AllDefault.class);
		StringBuilder codeTmpSb = new StringBuilder()
		.append("public void fillSafe(Object o) {\r\n")
		.append("	#CLASS obj = (#CLASS)o;\r\n")
		.append("	#SETLINES\r\n")
		.append("}");
		
		String codeTmp = codeTmpSb.toString();
		List<String> setLineList = new ArrayList<String>();
		BeanInfo beanInfo = Introspector.getBeanInfo(clazz);  
		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();  
		for (PropertyDescriptor property : propertyDescriptors) {
		    String key = property.getName();  
		    Field field = FieldUtils.getField(clazz, key, true);
		    if(field!=null){
				{
					IgnoreDefault defaultAnn = field.getAnnotation(IgnoreDefault.class);
					if(defaultAnn!=null){
						continue;
					}
				}
		    	{
			    	StringDefault defaultAnn = field.getAnnotation(StringDefault.class);
			    	if(defaultAnn!=null){
			        	String defaultValue = defaultAnn.value();
			    		Method readMethod = property.getReadMethod();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("if (obj.",readMethod.getName(),"() == null){"));
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(\"",defaultValue,"\");"));
			    		setLineList.add("}");
			    		continue;
			    	}
		    	}
		    	{
			    	BooleanDefault defaultAnn = field.getAnnotation(BooleanDefault.class);
			    	if(defaultAnn!=null){
			        	boolean defaultValue = defaultAnn.value();
			    		Method readMethod = property.getReadMethod();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("if (obj.",readMethod.getName(),"() == null){"));
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Boolean.valueOf(",defaultValue,"));"));
			    		setLineList.add("}");
			    		continue;
			    	}
		    	}
		    	{
			    	ShortDefault defaultAnn = field.getAnnotation(ShortDefault.class);
			    	if(defaultAnn!=null){
			        	short defaultValue = defaultAnn.value();
			    		Method readMethod = property.getReadMethod();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("if (obj.",readMethod.getName(),"() == null){"));
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Short.valueOf((short)",defaultValue,"));"));
			    		setLineList.add("}");
			    		continue;
			    	}
		    	}
		    	{
			    	IntegerDefault defaultAnn = field.getAnnotation(IntegerDefault.class);
			    	if(defaultAnn!=null){
			        	int defaultValue = defaultAnn.value();
			    		Method readMethod = property.getReadMethod();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("if (obj.",readMethod.getName(),"() == null){"));
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Integer.valueOf(",defaultValue,"));"));
			    		setLineList.add("}");
			    		continue;
			    	}
		    	}
		    	{
			    	LongDefault defaultAnn = field.getAnnotation(LongDefault.class);
			    	if(defaultAnn!=null){
			        	long defaultValue = defaultAnn.value();
			    		Method readMethod = property.getReadMethod();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("if (obj.",readMethod.getName(),"() == null){"));
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Long.valueOf(",defaultValue,"L));"));
			    		setLineList.add("}");
			    		continue;
			    	}
		    	}
		    	{
			    	FloatDefault defaultAnn = field.getAnnotation(FloatDefault.class);
			    	if(defaultAnn!=null){
			        	float defaultValue = defaultAnn.value();
			    		Method readMethod = property.getReadMethod();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("if (obj.",readMethod.getName(),"() == null){"));
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Float.valueOf(",defaultValue,"F));"));
			    		setLineList.add("}");
			    		continue;
			    	}
		    	}
		    	{
			    	DoubleDefault defaultAnn = field.getAnnotation(DoubleDefault.class);
			    	if(defaultAnn!=null){
			        	double defaultValue = defaultAnn.value();
			    		Method readMethod = property.getReadMethod();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("if (obj.",readMethod.getName(),"() == null){"));
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(Double.valueOf(",defaultValue,"));"));
			    		setLineList.add("}");
			    		continue;
			    	}
		    	}
		    	{
			    	DateDefaultNow defaultAnn = field.getAnnotation(DateDefaultNow.class);
			    	if(defaultAnn!=null){
			    		Method readMethod = property.getReadMethod();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("if (obj.",readMethod.getName(),"() == null){"));
						setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(org.apache.commons.lang3.time.DateUtils.truncate(new java.util.Date(),"+defaultAnn.truncate()+"));"));
			    		setLineList.add("}");
			    		continue;
			    	}
		    	}
		    	{
			    	SqlDateDefaultNow defaultAnn = field.getAnnotation(SqlDateDefaultNow.class);
			    	if(defaultAnn!=null){
			    		Method readMethod = property.getReadMethod();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("if (obj.",readMethod.getName(),"() == null){"));
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(new java.sql.Date(java.lang.System.currentTimeMillis()));"));
			    		setLineList.add("}");
			    		continue;
			    	}
		    	}
		    	{
			    	SqlTimeDefaultNow defaultAnn = field.getAnnotation(SqlTimeDefaultNow.class);
			    	if(defaultAnn!=null){
			    		Method readMethod = property.getReadMethod();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("if (obj.",readMethod.getName(),"() == null){"));
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(new java.sql.Time(java.lang.System.currentTimeMillis()));"));
			    		setLineList.add("}");
			    		continue;
			    	}
		    	}
		    	{
		    		BigDecimalDefault defaultAnn = field.getAnnotation(BigDecimalDefault.class);
			    	if(defaultAnn!=null){
			        	String defaultValue = defaultAnn.value();
			    		Method readMethod = property.getReadMethod();
			    		Method writeMethod = property.getWriteMethod();
			    		setLineList.add(StringUtils.join("if (obj.",readMethod.getName(),"() == null){"));
			    		setLineList.add(StringUtils.join("obj.",writeMethod.getName(),"(new java.math.BigDecimal(\"",defaultValue,"\"));"));
			    		setLineList.add("}");
			    		continue;
			    	}
		    	}
				{
					if(allDefault !=null){
						if(field.getType().equals(String.class)){
							setLineList.add(StringUtils.join("if (obj.",property.getReadMethod().getName(),"() == null){"));
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(\"\");"));
							setLineList.add("}");
						}else if(field.getType().equals(Boolean.class)){
							setLineList.add(StringUtils.join("if (obj.",property.getReadMethod().getName(),"() == null){"));
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Boolean.valueOf(false));"));
							setLineList.add("}");
						}else if(field.getType().equals(Short.class)){
							setLineList.add(StringUtils.join("if (obj.",property.getReadMethod().getName(),"() == null){"));
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Short.valueOf((short)0));"));
							setLineList.add("}");
						}else if(field.getType().equals(Integer.class)){
							setLineList.add(StringUtils.join("if (obj.",property.getReadMethod().getName(),"() == null){"));
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Integer.valueOf(0));"));
							setLineList.add("}");
						}else if(field.getType().equals(Long.class)){
							setLineList.add(StringUtils.join("if (obj.",property.getReadMethod().getName(),"() == null){"));
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Long.valueOf(0L));"));
							setLineList.add("}");
						}else if(field.getType().equals(Float.class)){
							setLineList.add(StringUtils.join("if (obj.",property.getReadMethod().getName(),"() == null){"));
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Float.valueOf(0.0F));"));
							setLineList.add("}");
						}else if(field.getType().equals(Double.class)){
							setLineList.add(StringUtils.join("if (obj.",property.getReadMethod().getName(),"() == null){"));
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(Double.valueOf(0.0));"));
							setLineList.add("}");
						}else if(field.getType().equals(BigDecimal.class)){
							setLineList.add(StringUtils.join("if (obj.",property.getReadMethod().getName(),"() == null){"));
							setLineList.add(StringUtils.join("obj.",property.getWriteMethod().getName(),"(java.math.BigDecimal.ZERO);"));
							setLineList.add("}");
						}
					}
				}
		    }
		}
		String setlines = StringUtils.join(setLineList,"\r\n\t");
		String code  = StringUtils.replace(codeTmp,"#CLASS", clazz.getName());
		code = StringUtils.replace(code,"#SETLINES", setlines);
		CtMethod methodBuildCt = CtNewMethod.make(code,defaultValueBuilderCt);
		defaultValueBuilderCt.addMethod(methodBuildCt);
	};


}
